Ratnopam Chakrabarti is a software developer currently working for Ericsson Inc. He has been focused on IoT, machine-to-machine technologies, connected cars, and smart city domains for quite a while. He loves learning new technologies and putting them to work. When he’s not working, he enjoys spending time with his 3-year-old son.
In Part 1 of this blog series, we looked at how we can store and retrieve image metadata to and from a Couchbase bucket. In this post (Part 2), we will take a look at the “likes” and show by tagname features of the app.
The idea here is to use HTML and jQuery on the client side that interact with the node components such as route.js running on the server side. For instance, the following jQuery snippet sits on the client side and makes an Ajax call to the “URL” which is exposed as a route inside route.js on the server side.
The like is an anchor element on click of which a new route gets called in the node app. Here’s the snippet:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
$(document).on('click', '.like', function(e){ console.log('Like clicked'); var that = $(this); var URL = host + '/like/' + that.data('photoid'); ajax({ url: URL, success:function(data){ var parseData = JSON.parse(data.response); that.find('h4').html(parseData.likes); } }) }) |
The URL is formed by appending the ‘/like/’ and the id of the image to the host variable. Once the Ajax call is made with success, the corresponding success callback parses the JSON response sent back from the server side (routes.js) endpoint.
The corresponding route for this (in routes.js) is shown below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
router.get('/like/:id', function(req, res, next){ ImageModel.getByDocumentId(req.params.id, function(err, result){ var jsonFromDB = JSON.stringify(result); var docFromDBArr = JSON.parse(jsonFromDB); var docFromDB = docFromDBArr[0]; var likes = docFromDB.likes; // increment the like by 1 likes = likes + 1; docFromDB.likes = likes; ImageModel.save(docFromDB, function(error, result) { if(error) { return res.status(400).send(error); } res.status(200).send({likes:docFromDB.likes}); }) }) }) |
The above route serves the call from the client side jQuery and also sends back a HTTP response of 200 and a JSON response body.
The route makes a call to the getByDocumentId function exposed by the ImageModel. This function, as shown below, retrieves a document from the Couchbase bucket based on the document id passed as an argument. Once the document is retrieved successfully, the result is parsed and the “likes” is incremented by 1. The updated document is saved by calling the save() function.
The getByDocumentId function (defined in recordmodel.js file):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/* * Get a particular document from Couchbase Server using a parameterized N1QL query */ ImageModel.getByDocumentId = function(documentId, callback) { var statement = "SELECT META(photos).id, filename, likes, tags " + "FROM `" + config.couchbase.bucket + "` AS photos " + "WHERE META(photos).id = $1"; var query = N1qlQuery.fromString(statement); db.query(query, [documentId], function(error, result) { if(error) { return callback(error, null); } callback(null, result); }); }; |
Show Images by TagName
To list images by a particular tag, we need to do the following things:
- Pass the tagname when the anchor is clicked
- Use the tagname to filter out images
The tagname is passed by the following simple jQquery:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$(document).on('click', '.showTag', function(e){ var that = $(this); var tagURL = host + '/getimages/' + that.data('tagname'); ajax({ url: tagURL, success:function(data){ var imageList = JSON.parse(data.response); renderImagesByTag (imageList); } }) }) |
And the corresponding route:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
router.get('/getimages/:tagname', function(req, res, next){ console.log('inside getimages by tagname'); ImageModel.getImagesByTag(req.params.tagname, function(err, result){ var jsonFromDB = JSON.stringify(result); res.send(JSON.stringify(result)); }) }) |
The getImagesByTag function is described below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
ImageModel.getImagesByTag = function(tagName, callback) { var statement = "SELECT META(photos).id, filename, likes, tags " + "FROM `" + config.couchbase.bucket + "` AS photos WHERE $1 IN tags"; var query = N1qlQuery.fromString(statement); db.query(query, [tagName], function(error, result) { if(error) { return callback(error, null); } callback(null, result); }); }; |
It simply runs the following query using N1QL:
select filename, likes from photogallery where <tagname> IN tags;
This allows filtering on the basis of tagname where tags is an array of strings.
So, if we have two images with the same tag then the above query should return both images.
Here both the documents have a common tag named “Blossom.” Now, if we run the query using the Couchbase Query Workbench, we get the following result:
As expected, you can see two records are returned. This is in effect what’s happening in the getImagesByTag () function.
Troubleshooting
During npm-install, if you face the following error,
Can’t find Python executable “python,” you can set the PYTHON env variable
then do the following to get rid of the error:
Install python
Add python to the path
This should resolve the error … at least it did for me.
This post is part of the Couchbase Community Writing Program